/**
 * @addtogroup brd_axis
 * brd_axis
 * @{
 */
/**
 * @file brd_axis.h
 * @brief 轴传感器(包括3轴, 6轴传感器)板级层
 * @date 2020-09-30
 * @par 修改日志
 * <table>
 * <tr><th>Date <th>Version <th>Author <th>Description
 * <tr><td>2020-09-30 <td>1.0 <td>软件工程院 <td>创建初始版本
 * @par 示例
 * @code
 * 创建一个设备(以Lsm6dsl为例).
   Brd_TAxisData buf;
   Brd_THandle handle = Brd_AxisCreate(id);
   Brd_AxisPowerSupply(handle, kBrd_PowerSupplyOn);
   ...
   Brd_AxisOpen(handle);

 * 若不知板子具体贴轴的情况 则将上述代码改为如下逻辑(只作为参考思路 勿完全照搬)
   Brd_TAxisData buf;
   Brd_THandle handle[kBrd_AxisIdMax];
   for (int i = kBrd_AxisIdMax - 1; i > 0; i--)
   {
      Brd_THandle temp_handle = Brd_AxisCreate(i);
      if (Brd_AxisOpen(temp_handle) == kBrd_ErrorCodeSuccess)
         handle[i] = temp_handle;
      else
      {
         Brd_AxisFree(temp_handle);
         handle[i] = NULL;
      }

      if (handle[i] != NULL)
      {
         Int32 id = Brd_AxisId(handle[i]);  // 设备id
         switch (id)
         {
            case kBrd_AxisIdLsm6dsl:
               Brd_AxisSetGyroscopeRange(handle[id], kBrd_AxisLsm6dslGyroRange500dps);  // 如设置为±500dps
               Brd_AxisSetAccelerometerRange(handle[id], kBrd_AxisLsm6dslAcceRange8g);  // 如设置为±8g
               Brd_AxisSetFreq(handle[id], kBrd_AxisFreq104Hz);  // 如设置为104Hz的数据频率
               SfSleep(100); // 具体延迟时间 > 输出频率的倒数即可
               // Brd_AxisSetAccelerometerWakeup(handle[id], thr); // 正常模式可自行选择是否开阈值中断 thr大小自定义 
               break;
            case kBrd_AxisIdDa280b:
               Brd_AxisSetAccelerometerRange(handle[id], kBrd_AxisDa280bAcceRange8g);  // 如设置为±8g
               Brd_AxisSetFreq(handle[id], kBrd_AxisDa280bFreq125Hz);  // 如设置为125Hz的数据频率
               SfSleep(100); // 具体延迟时间 > 输出频率的倒数即可
               // Brd_AxisSetAccelerometerWakeup(handle[id], thr); // 正常模式可自行选择是否开阈值中断 thr大小自定义 
               break;

               ...

            default:
               break;  
         }
      }
   }
   ...
   if (handle[xxx] != NULL)
      Brd_AxisGetData(handle[xxx], &buf); ///< xxx具体填想获取轴的id
   ..

 * 正常使用(以Lsm6dsl为例)
   Brd_AxisSetGyroscopeRange(handle, kBrd_AxisLsm6dslGyroRange500dps);  // 如设置为±500dps
   Brd_AxisSetAccelerometerRange(handle, kBrd_AxisLsm6dslAcceRange8g);  // 如设置为±8g
   Brd_AxisSetFreq(handle, kBrd_AxisFreq104Hz);  // 如设置为104Hz的数据频率
   SfSleep(100); // 具体延迟时间 > 输出频率的倒数即可
   // Brd_AxisSetAccelerometerWakeup(attr->handle, thr); // 正常模式可自行选择是否开阈值中断 thr大小自定义 
   ...
   Brd_AxisGetData(handle, &buf);
   ..
 * 关闭使用(以Lsm6dsl为例)
 * 补充说明:由于在改变量程范围的过程 会导致测量数据异常 若正常使用的情况下有用到阈值中断 且阈值较小的情况下会导致阈值中断异常触发 \n
 * 为避免阈值异常中断 可在切换量程前 先设置阈值为较大值(如:32768-1) 再改变范围和频率 延迟一段时间后再设置想要的阈值大小 可避免异常中断问题 \n
   Brd_AxisSetAccelerometerWakeup(attr->handle, 32768 - 1); 
   Brd_AxisSetAccelerometerRange(attr->handle, kBrd_AxisLsm6dslAcceRange2g);
   Brd_AxisSetFreq(handle, kBrd_AxisFreq13Hz);
   SfSleep(100); // 具体延迟时间 > 输出频率的倒数即可
   Brd_AxisSetWakeupThreshold(handle, 1 * 32768 / 2);  // 如设置超过±1g唤醒

   // 震动唤醒, 不能设置为kBrd_AxisFreq0Hz
      // Brd_AxisSetFreq(handle, kBrd_AxisFreq13Hz);
   // 否则进入低功耗, 停止产生数据
      // Brd_AxisSetFreq(handle, kBrd_AxisFreq0Hz);
   Brd_AxisClose(handle);
   Brd_AxisPowerSupply(handle, kBrd_PowerSupplyOff);
   ...
   Brd_AxisFree(handle);
 * @endcode
 * @copyright 杭州鸿泉物联网技术股份有限公司
 */

#ifndef _BRD_AXIS_H_
#define _BRD_AXIS_H_

#include <ofc_types.h>
#include <hcc_error_code.h>
#include "brd_common.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 * 传感器多轴数据
 */
struct Brd_TAxisDataTag
{
    Int16 gx;                                   ///< 陀螺仪X轴角速度数据, 单位(量程/32768)dps
    Int16 gy;                                   ///< 陀螺仪Y轴角速度数据, 单位(量程/32768)dps
    Int16 gz;                                   ///< 陀螺仪Z轴角速度数据, 单位(量程/32768)dps
    Int16 ax;                                   ///< 加速度计X轴加速度数据, 单位(量程/32768)g
    Int16 ay;                                   ///< 加速度计Y轴加速度数据, 单位(量程/32768)g
    Int16 az;                                   ///< 加速度计Z轴加速度数据, 单位(量程/32768)g
};
typedef struct Brd_TAxisDataTag Brd_TAxisData;

/**
 * 根据标识创建句柄
 * @param id: 标识, 参见[brd_def](@ref Brd_TAxisIdTag)
 * @return 当返回值为非 NULL 时, 表示创建成功, \n
 *         当返回值为 NULL 时, 表示创建失败, 原因为类型不支持
 */
Brd_THandle Brd_AxisCreate(Int32 id);

/**
 * 释放句柄
 * @param handle: 句柄
 * @return 当无返回值
 */
void Brd_AxisFree(Brd_THandle handle);

/**
 * 获取标识
 * @param handle: 句柄
 * @return 返回用于创建句柄的标识
 */
Int32 Brd_AxisId(Brd_THandle handle);

/**
 * 设备供电
 * @note 设备操作的前提, 需要先供电, 所有操作完成后需要停止供电以降低功耗
 * @param handle: 句柄
 * @param power : 设备供电类型, 参见[brd_def](@ref Brd_TPowerSupplyTag)
 * @return 当返回值 >= 0 时, 表示控制成功 \n
 *         当返回值 < 0 时, 表示控制失败参见[brd_def](@ref Brd_TErrorCodeTag)
 */
Int32 Brd_AxisPowerSupply(Brd_THandle handle, Int32 power);

/**
 * 打开设备
 * @param handle: 句柄
 * @return 当返回值 >= 0 时, 表示打开成功 \n
 *         当返回值 < 0 时, 表示打开失败参见[brd_def](@ref Brd_TErrorCodeTag)
 */
Int32 Brd_AxisOpen(Brd_THandle handle);

/**
 * 关闭设备
 * @param handle: 句柄
 * @return 当返回值 >= 0 时, 表示关闭成功 \n
 *         当返回值 < 0 时, 表示关闭失败参见[brd_def](@ref Brd_TErrorCodeTag)
 */
Int32 Brd_AxisClose(Brd_THandle handle);

/**
 * 设置陀螺仪量程
 * @note 需要在[Brd_AxisOpen](@ref Brd_AxisOpen)后调用
 * @param handle: 句柄
 * @param range: 量程值, 参见[brd_def](@ref Brd_TAxisLsm6dslGyroRangeTag)
 * @return 当返回值 >= 0 时, 表示设置成功 \n
 *         当返回值 < 0 时, 表示设置失败参见[brd_def](@ref Brd_TErrorCodeTag)
 */
Int32 Brd_AxisSetGyroscopeRange(Brd_THandle handle, Int32 range);

/**
 * 设置加速度计量程
 * @note 需要在[Brd_AxisOpen](@ref Brd_AxisOpen)后调用
 * @param handle: 句柄
 * @param range: 量程值, 参见[brd_def](@ref Brd_TAxisLsm6dslAcceRangeTag)
 * @return 当返回值 >= 0 时, 表示设置成功 \n
 *         当返回值 < 0 时, 表示设置失败参见[brd_def](@ref Brd_TErrorCodeTag)
 */
Int32 Brd_AxisSetAccelerometerRange(Brd_THandle handle, Int32 range);

/**
 * 设置数据产生频率
 * @note 需要在[Brd_AxisOpen](@ref Brd_AxisOpen)后调用
 *       当设置freq = 0时, 设备停止产生数据, 进入低功耗
 * @param handle: 句柄
 * @param freq: 频率值, 参见[brd_def](@ref Brd_TAxisLsm6dslFreqTag)
 * @return 当返回值 >= 0 时, 表示设置成功 \n
 *         当返回值 < 0 时, 表示设置失败参见[brd_def](@ref Brd_TErrorCodeTag)
 */
Int32 Brd_AxisSetFreq(Brd_THandle handle, Int32 freq);

/**
 * 设置加速度计唤醒阈值
 * @note 
 *       1. 需要在[Brd_AxisOpen](@ref Brd_AxisOpen)后调用
 *       2. 需要在设备关闭[Brd_AxisClose](@ref Brd_AxisClose)之前调用 \n
 *       3. 震动唤醒需要配合加速度计的量程及输出频率使用, 且频率不能设置为 kBrd_AxisFreq0Hz
 * @param handle: 句柄
 * @param value: 设备唤醒阈值, 单位为(量程/32768)g
 * @return 当返回值 >= 0 时, 表示设置成功 \n
 *         当返回值 < 0 时, 表示设置失败参见[brd_def](@ref Brd_TErrorCodeTag)
 */
Int32 Brd_AxisSetAccelerometerWakeup(Brd_THandle handle, Int32 value);

/**
 * 获取设备单个数据值
 * @note 需要在[Brd_AxisOpen](@ref Brd_AxisOpen)后调用
 * @param handle: 句柄
 * @param item: 存放设备数据缓存指针
 * @return 当返回值 >= 0 时, 表示获取成功 \n
 *         当返回值 < 0 时, 表示获取失败参见[brd_def](@ref Brd_TErrorCodeTag)
 */
Int32 Brd_AxisGetData(Brd_THandle handle, Brd_TAxisData *item);

/**
 * 获取设备多个数据值
 * @note 需要在[Brd_AxisOpen](@ref Brd_AxisOpen)后调用
 * @param handle: 句柄
 * @param items: 存放设备数据缓存指针
 * @param count: 数据个数
 * @return 当返回值 >= 0 时, 表示获取成功并返回实际读取的个数 \n
 *         当返回值 < 0 时, 表示获取失败参见[brd_def](@ref Brd_TErrorCodeTag)
 */
Int32 Brd_AxisGetMultiData(Brd_THandle handle, Brd_TAxisData *items, Int32 count);

/**
 * 获取设备温度值
 * @note 需要在[Brd_AxisOpen](@ref Brd_AxisOpen)后调用
 *    -# 传感器自带的温度不精准, 偏差在-15~15℃
 * @param handle: 句柄
 * @param value: 温度值指针
 * @return 当返回值 >= 0 时, 表示获取成功 \n
 *         当返回值 < 0 时, 表示获取失败参见[brd_def](@ref Brd_TErrorCodeTag)
 */
Int32 Brd_AxisGetTemp(Brd_THandle handle, Int32 *value);

/**
 * 设置FIFO模式
 * @note:
 *  需要在设备打开(Brd_AxisOpen)之后调用
 * @param self: 对象实例指针
 * @param mode: 模式
 * @return 成功返回0,其它参见[Brd_TErrorCodeTag]
 */
Int32 Brd_AxisSetFifoMode(Brd_THandle handle, Int32 mode);

/**
 * 设置FIFO数据产生频率
 * @note:
 *  需要在设备打开(Brd_AxisOpen)之后调用
 * @param self: 对象实例指针
 * @param freq: 频率值
 * @return 成功返回0,其它参见[Brd_TErrorCodeTag]
 */
Int32 Brd_AxisSetFifoFreq(Brd_THandle handle, Int32 freq);

/**
 * 设置FIFO数据深度阈值
 * @note:
 *  需要在设备打开(Brd_AxisOpen)之后调用
 * @param self: 对象实例指针
 * @param ths: 阈值
 * @return 成功返回0,其它参见[Brd_TErrorCodeTag]
 */
Int32 Brd_AxisSetFifoThreshold(Brd_THandle handle, Int32 ths);

/**
 * 获取FIFO数据
 * @note:
 *  需要在设备打开(Brd_AxisOpen)之后调用
 * @param self: 对象实例指针
 * @param buf: 获取数据缓存
 * @param size: 获取数据缓存大小
 * @param data_size: 未读数据大小
 * @return 成功返回获取数据大小,其它参见[Brd_TErrorCodeTag]
 */
Int32 Brd_AxisGetFifoData(Brd_THandle handle, UInt8* buf, UInt32 size, Int32 *data_size);

/**
 * FIFO缓存区重置
 * @note:
 *  需要在设备打开(Brd_AxisOpen)之后调用，只针对fifo模式
 * @param self: 对象实例指针
 * @return 成功返回0,其它参见[Brd_TErrorCodeTag]
 */
Int32 Brd_AxisFifoReset(Brd_THandle handle);

#ifdef __cplusplus
}  ///< extern "C"
#endif

#endif // _BRD_AXIS_H_
/**
 * @} 
 */
